package net.goutalk.glcs.module.system.service.impl;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.sql.Direction;
import cn.hutool.db.sql.Order;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import com.github.yulichang.base.MPJBaseServiceImpl;
import net.goutalk.glcs.common.utils.DatasourceUtil;
import net.goutalk.glcs.module.system.dto.GetDataPageDto;
import net.goutalk.glcs.module.system.entity.Databaselink;
import net.goutalk.glcs.module.system.entity.Datasource;
import net.goutalk.glcs.module.system.mapper.DatabaselinkMapper;
import net.goutalk.glcs.module.system.mapper.DatasourceMapper;
import net.goutalk.glcs.module.system.service.IDatasourceService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.*;

/**
 * <p>
 * 数据源表 服务实现类
 * </p>
 *
 * @author tanyujie
 * @since 2022-03-08
 */
@Service
@AllArgsConstructor
public class DatasourceServiceImpl extends MPJBaseServiceImpl<DatasourceMapper, Datasource> implements IDatasourceService {

    private final DatasourceMapper datasourceMapper;

    private final DatabaselinkMapper databaselinkMapper;

    @Override
    @SneakyThrows
    public List<String> getColumns(Long id) {
        Datasource datasource = datasourceMapper.selectById(id);
        Entity entity = Db.use(DatasourceUtil.getDataSource(datasource.getDatabaselinkId().toString())).queryOne(datasource.getSqlScript());
        Set<String> fieldNames = entity.getFieldNames();
        return new ArrayList<>(fieldNames);
    }

    @Override
    @SneakyThrows
    public List<Entity> getData(Long id) {
        Datasource datasource = datasourceMapper.selectById(id);
        return Db.use(DatasourceUtil.getDataSource(datasource.getDatabaselinkId().toString())).query(datasource.getSqlScript());
    }

    @Override
    @SneakyThrows
    public Map<String, Object> getDataPage(GetDataPageDto dto) {
        Datasource datasource = datasourceMapper.selectById(dto.getId());
        Long dbId = datasource.getDatabaselinkId();
        Databaselink databaselink = databaselinkMapper.selectById(dbId);
        DataSource dbSource = null;
        DbType dbType = null;
        if (Long.valueOf(0L).equals(dbId)) {
            dbSource = DatasourceUtil.getDatasourceMaster();
            dbType = DatasourceUtil.getDataSourceMasterDbType();
        } else if (databaselink != null) {
            dbSource = DatasourceUtil.getDataSource(String.valueOf(dbId));
            dbType = JdbcUtils.getDbType(databaselink.getHost());
        } else {
            throw new RuntimeException("数据库连接不存在！");
        }

        Order order = new Order(dto.getField(), Direction.fromString(dto.getOrder()));
        Page page = new Page((int) dto.getLimit() - 1, (int) dto.getSize(),order);

        String pageSql = DatasourceUtil.wrapperPageSql(datasource.getSqlScript(), page, dbType);

        List<Entity> dataPage = Db.use(dbSource).query(pageSql);
        long count = Db.use(dbSource).count(datasource.getSqlScript());

        Map<String, Object> map = new HashMap<>(2);
        map.put("list", dataPage);
        map.put("total", count);
        return map;
    }
}
